home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / MAP Viewer / MainForm.cpp < prev    next >
C/C++ Source or Header  |  2003-10-09  |  43KB  |  1,353 lines

  1. /*
  2. Half-Life MAP viewing utility.
  3. Copyright (C) 2003  Ryan Samuel Gregg
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18. */
  19.  
  20. #include "stdafx.h"
  21. #include "MainForm.h"
  22.  
  23. CMainForm::CMainForm(String *sStartupMAP, CConfig *Config)
  24. {
  25.     this->bCloseing = false;
  26.     this->sStartupMAP = sStartupMAP;
  27.  
  28.     RecentFiles = new ArrayList();
  29.  
  30.     this->txtConsole = new ::CRichTextBox();
  31.     
  32.     this->Config = Config;
  33.     this->Engine = new CEngine(Config, this->txtConsole);
  34.     this->MAPLoader = new CMAPLoader(Config, this->txtConsole);
  35.     this->PTSLoader = new CPTSLoader(Config, this->txtConsole);
  36.  
  37.     this->AboutForm = new CAboutForm("1.0.1", "Ryan Gregg", "02/09/2003", "C++", "5,668");
  38.  
  39.     this->mnuMainMenu = new ::MainMenu();
  40.  
  41.     this->cmdFile = new ::MenuItem("&File");
  42.     this->cmdOpen = new ::MenuItem("&Open");
  43.     this->cmdFileSep1 = new ::MenuItem("-");
  44.     this->cmdRecentFiles = new ::MenuItem("&Recent Files");
  45.     this->cmdFileSep2 = new ::MenuItem("-");
  46.     this->cmdExit = new ::MenuItem("E&xit");
  47.  
  48.     this->cmdView = new ::MenuItem("&View");
  49.     this->cmdTextured = new ::MenuItem("&Textured");
  50.     this->cmdSolid = new ::MenuItem("&Solid");
  51.     this->cmdWireFrame = new ::MenuItem("&Wireframe");
  52.     this->cmdPoints = new ::MenuItem("&Points");
  53.     this->cmdViewSep1 = new ::MenuItem("-");
  54.     this->cmdDrawSpecialTextures = new ::MenuItem("Draw Special &Textures");
  55.     this->cmdDrawSelection = new ::MenuItem("Draw &Selection");
  56.     this->cmdDrawPointFile = new ::MenuItem("Draw &Point File");
  57.     this->cmdViewSep2 = new ::MenuItem("-");
  58.     this->cmdOutlineScene = new ::MenuItem("&Outline Scene");
  59.     this->cmdLightScene = new ::MenuItem("&Light Scene");
  60.     this->cmdViewSep3 = new ::MenuItem("-");
  61.     this->cmdFog = new ::MenuItem("&Fog");
  62.     this->cmdViewSep4 = new ::MenuItem("-");
  63.     this->cmdTextureFilter = new ::MenuItem("Texture &Filter");
  64.     this->cmdNonMipmapped = new ::MenuItem("&Non-Mipmapped");
  65.     this->cmdMipmapped = new ::MenuItem("&Mipmapped");
  66.     this->cmdNearest = new ::MenuItem("&Nearest");
  67.     this->cmdLinear = new ::MenuItem("&Linear");
  68.     this->cmdMipNearest = new ::MenuItem("&Nearest");
  69.     this->cmdMipLinear = new ::MenuItem("&Linear");
  70.     this->cmdMipBilinear = new ::MenuItem("&Bilinear");
  71.     this->cmdMipTrilinear = new ::MenuItem("&Trilinear");
  72.     this->cmdMipIsotropic = new ::MenuItem("&Isotropic");
  73.     this->cmdMipAnisotropic = new ::MenuItem("&Anisotropic");
  74.  
  75.     this->cmdPointFile = new ::MenuItem("&Point File");
  76.     this->cmdLoadPointFile = new ::MenuItem("&Load Point File");
  77.     this->cmdUnloadPointFile = new ::MenuItem("&Unload Point File");
  78.  
  79.     this->cmdHelp = new ::MenuItem("&Help");
  80.     this->cmdAbout = new ::MenuItem("&About");
  81.  
  82.     this->dlgOpenMAPFile = new ::OpenFileDialog();
  83.     this->dlgOpenPTSFile = new ::OpenFileDialog();
  84.  
  85.     this->barStatusMain = new ::StatusBar();
  86.  
  87.     this->pnlSide = new ::Panel();
  88.     this->pnlMain = new ::Panel();
  89.     this->pnlBottom = new ::Panel();
  90.  
  91.     this->treWorld = new ::TreeView();
  92.     this->splProperties = new ::Splitter();
  93.     this->lstProperties = new ::ListView();
  94.  
  95.     this->splTree = new ::Splitter();
  96.  
  97.     this->pic3D = new ::PictureBox();
  98.  
  99.     this->splConsole = new ::Splitter();
  100.  
  101.     //this->txtConsole = new ::CRichTextBox();
  102.  
  103.     // Form Setup
  104.     this->Text = S"MAP Viewer";
  105.     this->AutoScaleBaseSize = ::Size(5, 13);
  106.     this->ClientSize = ::Size(800, 600);
  107.     this->StartPosition = ::FormStartPosition::CenterScreen;
  108.     this->WindowState = ::FormWindowState::Normal;
  109.  
  110.     // Setup Menu
  111.     this->mnuMainMenu->MenuItems->Add(this->cmdFile);
  112.     this->mnuMainMenu->MenuItems->Add(this->cmdView);
  113.     this->mnuMainMenu->MenuItems->Add(this->cmdPointFile);
  114.     this->mnuMainMenu->MenuItems->Add(this->cmdHelp);
  115.  
  116.     this->cmdRecentFiles->Visible = false;
  117.     this->cmdFileSep2->Visible = false;
  118.     this->cmdFile->MenuItems->Add(this->cmdOpen);
  119.     this->cmdFile->MenuItems->Add(this->cmdFileSep1);
  120.     this->cmdFile->MenuItems->Add(this->cmdRecentFiles);
  121.     this->cmdFile->MenuItems->Add(this->cmdFileSep2);
  122.     this->cmdFile->MenuItems->Add(this->cmdExit);
  123.  
  124.     this->cmdTextured->RadioCheck = true;
  125.     this->cmdSolid->RadioCheck = true;
  126.     this->cmdWireFrame->RadioCheck = true;
  127.     this->cmdPoints->RadioCheck = true;
  128.     this->cmdView->MenuItems->Add(this->cmdTextured);
  129.     this->cmdView->MenuItems->Add(this->cmdSolid);
  130.     this->cmdView->MenuItems->Add(this->cmdWireFrame);
  131.     this->cmdView->MenuItems->Add(this->cmdPoints);
  132.  
  133.     this->cmdLoadPointFile->Enabled = false;
  134.     this->cmdUnloadPointFile->Enabled = false;
  135.     this->cmdView->MenuItems->Add(this->cmdViewSep1);
  136.     this->cmdView->MenuItems->Add(this->cmdDrawSpecialTextures);
  137.     this->cmdView->MenuItems->Add(this->cmdDrawSelection);
  138.     this->cmdView->MenuItems->Add(this->cmdDrawPointFile);
  139.     this->cmdView->MenuItems->Add(this->cmdViewSep2);
  140.     this->cmdView->MenuItems->Add(this->cmdOutlineScene);
  141.     this->cmdView->MenuItems->Add(this->cmdLightScene);
  142.     this->cmdView->MenuItems->Add(this->cmdViewSep3);
  143.     this->cmdView->MenuItems->Add(this->cmdFog);
  144.     this->cmdView->MenuItems->Add(this->cmdViewSep4);
  145.     this->cmdView->MenuItems->Add(this->cmdTextureFilter);
  146.  
  147.     this->cmdPointFile->MenuItems->Add(this->cmdLoadPointFile);
  148.     this->cmdPointFile->MenuItems->Add(this->cmdUnloadPointFile);
  149.  
  150.     this->cmdHelp->MenuItems->Add(this->cmdAbout);
  151.  
  152.     this->cmdTextureFilter->MenuItems->Add(this->cmdNonMipmapped);
  153.     this->cmdTextureFilter->MenuItems->Add(this->cmdMipmapped);
  154.  
  155.     this->cmdNearest->RadioCheck = true;
  156.     this->cmdLinear->RadioCheck = true;
  157.     this->cmdNonMipmapped->MenuItems->Add(this->cmdNearest);
  158.     this->cmdNonMipmapped->MenuItems->Add(this->cmdLinear);
  159.  
  160.     this->cmdMipNearest->RadioCheck = true;
  161.     this->cmdMipLinear->RadioCheck = true;
  162.     this->cmdMipBilinear->RadioCheck = true;
  163.     this->cmdMipTrilinear->RadioCheck = true;
  164.     this->cmdMipIsotropic->RadioCheck = true;
  165.     this->cmdMipAnisotropic->RadioCheck = true;
  166.     this->cmdMipmapped->MenuItems->Add(this->cmdMipNearest);
  167.     this->cmdMipmapped->MenuItems->Add(this->cmdMipLinear);
  168.     this->cmdMipmapped->MenuItems->Add(this->cmdMipBilinear);
  169.     this->cmdMipmapped->MenuItems->Add(this->cmdMipTrilinear);
  170.     this->cmdMipmapped->MenuItems->Add(this->cmdMipIsotropic);
  171.     this->cmdMipmapped->MenuItems->Add(this->cmdMipAnisotropic);
  172.  
  173.     // Setup dialogs
  174.     dlgOpenMAPFile->Title = "Open MAP File";
  175.     dlgOpenMAPFile->Filter = "MAP Files (*.map)|*.map";
  176.  
  177.     dlgOpenPTSFile->Title = "Open PTS File";
  178.     dlgOpenPTSFile->Filter = "PTS Files (*.pts)|*.pts";
  179.  
  180.     // Setup Status Bar
  181.     this->barStatusMain->Dock = ::DockStyle::Bottom;
  182.  
  183.     // Setup Side Panel
  184.     this->pnlSide->Dock = ::DockStyle::Left;
  185.     this->pnlSide->Width = 160;
  186.  
  187.     // Setup Main Panel
  188.     this->pnlMain->Dock = ::DockStyle::Fill;
  189.  
  190.     // Setup Bottom Panel
  191.     this->pnlBottom->Dock = ::DockStyle::Bottom;
  192.     this->pnlBottom->Height = 160;
  193.  
  194.     // Setup Tree
  195.     this->treWorld->Dock = ::DockStyle::Top;
  196.     this->treWorld->Height = 256;
  197.  
  198.     // Setup Property Splitter
  199.     this->splProperties->Dock = ::DockStyle::Top;
  200.     
  201.     // Setup Properties
  202.     this->lstProperties->Dock = ::DockStyle::Fill;
  203.     this->lstProperties->FullRowSelect = true;
  204.     this->lstProperties->GridLines = true;
  205.     this->lstProperties->MultiSelect = false;
  206.     this->lstProperties->View = System::Windows::Forms::View::Details;
  207.     this->lstProperties->HeaderStyle = System::Windows::Forms::ColumnHeaderStyle::Nonclickable;
  208.  
  209.     ColumnHeader *Header;
  210.  
  211.     Header = new ColumnHeader();
  212.     Header->Text = "Arg";
  213.     this->lstProperties->Columns->Add(Header);
  214.  
  215.     Header = new ColumnHeader();
  216.     Header->Text = "Val";
  217.     this->lstProperties->Columns->Add(Header);
  218.  
  219.     // Setup Tree Splitter
  220.     this->splTree->Dock = ::DockStyle::Left;
  221.  
  222.     // Setup Picture Box
  223.     this->pic3D->Dock = ::DockStyle::Fill;
  224.     this->pic3D->BackColor = ::SystemColors::ControlDark;
  225.  
  226.     // Setup Console Splitter
  227.     this->splConsole->Dock = ::DockStyle::Bottom;
  228.     
  229.     // Setup Console
  230.     this->txtConsole->Dock = ::DockStyle::Bottom;
  231.     this->txtConsole->ReadOnly = true;
  232.     
  233.     // Add All Function Pointers
  234.     this->add_Closing(new ::CancelEventHandler(this, &CMainForm::CMainForm_Closeing));
  235.     this->add_Load(new ::EventHandler(this, &CMainForm::CMainForm_Load));
  236.  
  237.     this->pic3D->add_Resize(new ::EventHandler(this, &CMainForm::pic3D_Resize));
  238.     this->pic3D->add_Paint(new ::PaintEventHandler(this, &CMainForm::pic3D_Paint));
  239.     this->pic3D->add_MouseMove(new ::MouseEventHandler(this, &CMainForm::pic3D_MouseMove));
  240.     this->pic3D->add_MouseDown(new ::MouseEventHandler(this, &CMainForm::pic3D_MouseDown));
  241.     this->pic3D->add_MouseUp(new ::MouseEventHandler(this, &CMainForm::pic3D_MouseUp));
  242.     this->pic3D->add_KeyDown(new ::KeyEventHandler(this, &CMainForm::pic3D_KeyDown));
  243.     this->pic3D->add_KeyUp(new ::KeyEventHandler(this, &CMainForm::pic3D_KeyUp));
  244.  
  245.     this->treWorld->add_AfterSelect(new ::TreeViewEventHandler(this, &CMainForm::treWorld_AfterSelect));
  246.     this->lstProperties->add_Resize(new ::EventHandler(this, &CMainForm::lstProperties_Resize));
  247.  
  248.     this->cmdOpen->add_Click(new ::EventHandler(this, &CMainForm::cmdOpen_Click));
  249.     this->cmdExit->add_Click(new ::EventHandler(this, &CMainForm::cmdExit_Click));
  250.  
  251.     this->cmdTextured->add_Click(new ::EventHandler(this, &CMainForm::cmdTextured_Click));
  252.     this->cmdSolid->add_Click(new ::EventHandler(this, &CMainForm::cmdSolid_Click));
  253.     this->cmdWireFrame->add_Click(new ::EventHandler(this, &CMainForm::cmdWireFrame_Click));
  254.     this->cmdPoints->add_Click(new ::EventHandler(this, &CMainForm::cmdPoints_Click));
  255.     this->cmdDrawSpecialTextures->add_Click(new ::EventHandler(this, &CMainForm::cmdDrawSpecialTextures_Click));
  256.     this->cmdDrawSelection->add_Click(new ::EventHandler(this, &CMainForm::cmdDrawSelection_Click));
  257.     this->cmdDrawPointFile->add_Click(new ::EventHandler(this, &CMainForm::cmdDrawPointFile_Click));
  258.     this->cmdOutlineScene->add_Click(new ::EventHandler(this, &CMainForm::cmdOutlineScene_Click));
  259.     this->cmdLightScene->add_Click(new ::EventHandler(this, &CMainForm::cmdLightScene_Click));
  260.     this->cmdFog->add_Click(new ::EventHandler(this, &CMainForm::cmdFog_Click));
  261.  
  262.     this->cmdNearest->add_Click(new ::EventHandler(this, &CMainForm::cmdNearest_Click));
  263.     this->cmdLinear->add_Click(new ::EventHandler(this, &CMainForm::cmdLinear_Click));
  264.     this->cmdMipNearest->add_Click(new ::EventHandler(this, &CMainForm::cmdMipNearest_Click));
  265.     this->cmdMipLinear->add_Click(new ::EventHandler(this, &CMainForm::cmdMipLinear_Click));
  266.     this->cmdMipBilinear->add_Click(new ::EventHandler(this, &CMainForm::cmdMipBilinear_Click));
  267.     this->cmdMipTrilinear->add_Click(new ::EventHandler(this, &CMainForm::cmdMipTrilinear_Click));
  268.     this->cmdMipIsotropic->add_Click(new ::EventHandler(this, &CMainForm::cmdMipIsotropic_Click));
  269.     this->cmdMipAnisotropic->add_Click(new ::EventHandler(this, &CMainForm::cmdMipAnisotropic_Click));
  270.  
  271.     this->cmdLoadPointFile->add_Click(new ::EventHandler(this, &CMainForm::cmdLoadPointFile_Click));
  272.     this->cmdUnloadPointFile->add_Click(new ::EventHandler(this, &CMainForm::cmdUnloadPointFile_Click));
  273.  
  274.     this->cmdAbout->add_Click(new ::EventHandler(this, &CMainForm::cmdAbout_Click));
  275.  
  276.     // Add All Controls
  277.     this->pnlSide->Controls->Add(this->lstProperties);
  278.     this->pnlSide->Controls->Add(this->splProperties);
  279.     this->pnlSide->Controls->Add(this->treWorld);
  280.  
  281.     this->pnlMain->Controls->Add(this->pic3D);
  282.  
  283.     this->pnlBottom->Controls->Add(this->txtConsole);
  284.  
  285.     this->Menu = this->mnuMainMenu;
  286.     this->Controls->Add(this->pnlMain);
  287.     this->Controls->Add(this->splTree);
  288.     this->Controls->Add(this->pnlSide);
  289.     this->Controls->Add(this->splConsole);
  290.     this->Controls->Add(this->txtConsole);
  291.     this->Controls->Add(this->barStatusMain);
  292. }
  293.  
  294. void CMainForm::LoadWorld(String *sFileName)
  295. {
  296.     if(!File::Exists(sFileName))
  297.     {
  298.         txtConsole->Print(String::Concat(sFileName, " not found.\n"), Color::Red);
  299.         return;
  300.     }
  301.  
  302.     CWorld *World = new CWorld(Config);
  303.     CTextureManager *TextureManager = new CTextureManager(Config, this->txtConsole);
  304.  
  305.     if(this->MAPLoader->LoadMAPFile(sFileName, World, TextureManager))
  306.     {
  307.         this->Engine->SetWorld(World, TextureManager);
  308.  
  309.         txtConsole->Print("Building tree...", Color::Green);
  310.  
  311.         BuildTree(World);
  312.  
  313.         this->cmdLoadPointFile->Enabled = true;
  314.         this->cmdUnloadPointFile->Enabled = false;
  315.  
  316.         AddRecentFile(sFileName);
  317.         UpdateRecentFiles();
  318.  
  319.         this->barStatusMain->Text = String::Concat(sFileName, " loaded.");
  320.  
  321.         txtConsole->Print("done.\n", Color::Green);
  322.  
  323.         this->Engine->EnterRenderLoop();
  324.     }
  325.  
  326.     GC::Collect();
  327. }
  328.  
  329. void CMainForm::LoadPointFile(String *sFileName)
  330. {
  331.     CPointFile *PointFile;
  332.  
  333.     if(this->PTSLoader->LoadPTSFile(sFileName, &PointFile))
  334.     {
  335.         this->Engine->SetPointFile(PointFile);
  336.         this->cmdUnloadPointFile->Enabled = true;
  337.     }
  338. }
  339.  
  340. void CMainForm::UnloadPointFile()
  341. {
  342.     this->Engine->SetPointFile(NULL);
  343.     this->cmdUnloadPointFile->Enabled = false;
  344. }
  345.  
  346. void CMainForm::BuildTree(CWorld *World)
  347. {
  348.     this->treWorld->BeginUpdate();
  349.     this->treWorld->SelectedNode = NULL;
  350.     this->treWorld->Nodes->Clear();
  351.     this->lstProperties->Items->Clear();
  352.  
  353.     //Vertex3f Vertex;
  354.     CFace *Face;
  355.     CBrush *Brush;
  356.     CEntity *Entity;
  357.     CWorldObjectTreeNode *EntityNode, *BrushNode, *FaceNode;
  358.     String *Name;
  359.     for(int i = 0; i < World->GetEntities()->Count; i++)
  360.     {
  361.         Entity = static_cast<CEntity*>(World->GetEntities()->get_Item(i));
  362.         Name = Entity->GetName();
  363.         EntityNode = new CEntityTreeNode(Name, Entity);
  364.  
  365.         for(int j = 0; j < Entity->GetBrushes()->Count; j++)
  366.         {
  367.             Brush = static_cast<CBrush*>(Entity->GetBrushes()->get_Item(j));
  368.             Name = String::Concat(S"brush ", j.ToString());
  369.             BrushNode = new CBrushTreeNode(Name, Brush);
  370.  
  371.             for(int k = 0; k < Brush->GetFaces()->Count; k++)
  372.             {
  373.                 Face = static_cast<CFace*>(Brush->GetFaces()->get_Item(k));
  374.                 Name = String::Concat(S"face ", k.ToString());
  375.                 FaceNode = new CFaceTreeNode(Name, Face);
  376.  
  377.                 // Takes too much time...
  378.                 /*for(int l = 0; l < Face->GetVertexCount(); l++)
  379.                 {
  380.                     Vertex = Face->GetVertex(l);
  381.                     Name = String::Concat(Vertex.X.ToString(), S", ", Vertex.Y.ToString(), S", ", Vertex.Z.ToString());
  382.                     FaceNode->Nodes->Add(new TreeNode(Name));
  383.                 }*/
  384.  
  385.                 BrushNode->Nodes->Add(FaceNode);
  386.             }
  387.  
  388.             EntityNode->Nodes->Add(BrushNode);
  389.         }
  390.  
  391.         this->treWorld->Nodes->Add(EntityNode);
  392.     }
  393.  
  394.     this->treWorld->EndUpdate();
  395. }
  396.  
  397. void CMainForm::AddRecentFile(String *sFile)
  398. {
  399.     for(int i = 0; i < RecentFiles->Count; i++)
  400.     {
  401.         if(static_cast<String*>(RecentFiles->get_Item(i))->ToLower()->Equals(sFile->ToLower()))
  402.         {
  403.             if(i == 0)
  404.             {
  405.                 return;
  406.             }
  407.             else
  408.             {
  409.                 RecentFiles->RemoveAt(i);
  410.                 RecentFiles->Insert(0, sFile);
  411.  
  412.                 return;
  413.             }
  414.         }
  415.     }
  416.  
  417.     RecentFiles->Insert(0, sFile);
  418. }
  419.  
  420. void CMainForm::UpdateRecentFiles()
  421. {
  422.     ::MenuItem *cmdRecentFile;
  423.     cmdRecentFiles->MenuItems->Clear();
  424.  
  425.     while(RecentFiles->Count > Config->iRecentMAPCount)
  426.     {
  427.         RecentFiles->RemoveAt(RecentFiles->Count - 1);
  428.     }
  429.  
  430.     for(int i = 0; i < RecentFiles->Count; i++)
  431.     {
  432.         cmdRecentFile = new ::MenuItem(static_cast<String*>(RecentFiles->get_Item(i)));
  433.         cmdRecentFile->add_Click(new ::EventHandler(this, &CMainForm::cmdRecentFile_Click));
  434.         this->cmdRecentFiles->MenuItems->Add(cmdRecentFile);
  435.     }
  436.  
  437.     bool bDisplayRecentFiles = RecentFiles->Count != 0;
  438.     this->cmdRecentFiles->Visible = bDisplayRecentFiles;
  439.     this->cmdFileSep2->Visible = bDisplayRecentFiles;
  440. }
  441.  
  442. void CMainForm::Exit()
  443. {
  444.     this->bCloseing = true;
  445.  
  446.     this->Engine->ExitRenderLoop();
  447.     this->Engine->Destroy();
  448.  
  449.     txtConsole->Print("OpenGL destroyed.\n", Color::Green);
  450.  
  451.     WriteConfigFile(String::Concat(Application::StartupPath, "\\mv.ini"));
  452.  
  453.     this->txtConsole->SaveFile(String::Concat(Application::StartupPath, "\\log.txt"), RichTextBoxStreamType::PlainText);
  454.  
  455.     this->Close();
  456.     Application::Exit();
  457. }
  458.  
  459. void CMainForm::CMainForm_Load(::Object *sender, ::EventArgs *e)
  460. {
  461.     LoadConfigFile(String::Concat(Application::StartupPath, "\\mv.ini"));
  462.  
  463.     if(Config->sHalfLifePath->Length == 0)
  464.     {
  465.         GetHalfLifePath();
  466.     }
  467.  
  468.     if(!this->Engine->Initialize((HWND)this->pic3D->Handle.ToInt32()))
  469.     {
  470.         txtConsole->Print("Error initializing OpenGL engine.\n", Color::Red);
  471.     }
  472.     else
  473.     {
  474.         txtConsole->Print("OpenGL initialized.\n", Color::Green);
  475.     }
  476.  
  477.     this->Show();
  478.  
  479.     switch(Config->eRenderMode)
  480.     {
  481.         case RenderMode::Textured:
  482.             cmdTextured->Checked = true;
  483.             break;
  484.         case RenderMode::Solid:
  485.             cmdSolid->Checked = true;
  486.             break;
  487.         case RenderMode::WireFrame:
  488.             cmdWireFrame->Checked = true;
  489.             break;
  490.         case RenderMode::Points:
  491.             cmdPoints->Checked = true;
  492.             break;
  493.     }
  494.  
  495.     cmdDrawSpecialTextures->Checked = Config->bDrawSpecialTextures;
  496.  
  497.     cmdDrawSelection->Checked = Config->bDrawSelection;
  498.  
  499.     cmdDrawPointFile->Checked = Config->bDrawPointFile;
  500.  
  501.     cmdOutlineScene->Checked = Config->bOutlineScene;
  502.  
  503.     cmdLightScene->Checked = Config->bLightScene;
  504.  
  505.     cmdFog->Checked = Config->bFog;
  506.  
  507.     switch(Config->eTextureFilter)
  508.     {
  509.         case TextureFilter::Nearest:
  510.             cmdNearest->Checked = true;
  511.             break;
  512.         case TextureFilter::Linear:
  513.             cmdLinear->Checked = true;
  514.             break;
  515.         case TextureFilter::MipNearest:
  516.             cmdMipNearest->Checked = true;
  517.             break;
  518.         case TextureFilter::MipLinear:
  519.             cmdMipLinear->Checked = true;
  520.             break;
  521.         case TextureFilter::MipBilinear:
  522.             cmdMipBilinear->Checked = true;
  523.             break;
  524.         case TextureFilter::MipTrilinear:
  525.             cmdMipTrilinear->Checked = true;
  526.             break;
  527.         case TextureFilter::MipIsotropic:
  528.             cmdMipIsotropic->Checked = true;
  529.             break;
  530.         case TextureFilter::MipAnisotropic:
  531.             cmdMipAnisotropic->Checked = true;
  532.             break;
  533.     }
  534.  
  535.     this->Engine->Resize(this->pic3D->ClientSize.Width, this->pic3D->ClientSize.Height);
  536.  
  537.     if(sStartupMAP->Length != 0)
  538.     {
  539.         LoadWorld(sStartupMAP);
  540.     }
  541. }
  542.  
  543. void CMainForm::CMainForm_Closeing(::Object *sender, ::CancelEventArgs *e)
  544. {
  545.     if(!this->bCloseing)
  546.     {
  547.         e->Cancel = true;
  548.         this->Exit();
  549.     }
  550. }
  551.  
  552. void CMainForm::pic3D_Resize(::Object *sender, ::EventArgs *e)
  553. {
  554.     this->Engine->Resize(this->pic3D->ClientSize.Width, this->pic3D->ClientSize.Height);
  555. }
  556.  
  557. void CMainForm::pic3D_Paint(::Object *sender, ::PaintEventArgs *e)
  558. {
  559.     this->Engine->Paint();
  560. }
  561.  
  562. void CMainForm::pic3D_MouseMove(::Object *sender, ::MouseEventArgs *e)
  563. {
  564.     this->Engine->SetMousePosition(e->get_X(), e->get_Y());
  565. }
  566.  
  567. void CMainForm::pic3D_MouseDown(::Object *sender, ::MouseEventArgs *e)
  568. {
  569.     if(e->Button == MouseButtons::Left)
  570.     {
  571.         this->Engine->SetMousePressed(true);
  572.     }
  573.  
  574.     this->pic3D->Focus();
  575. }
  576.  
  577. void CMainForm::pic3D_MouseUp(::Object *sender, ::MouseEventArgs *e)
  578. {
  579.     if(e->Button == MouseButtons::Left)
  580.     {
  581.         this->Engine->SetMousePressed(false);
  582.     }
  583. }
  584.  
  585. void CMainForm::pic3D_KeyDown(::Object *sender, ::KeyEventArgs *e)
  586. {
  587.     Engine->SetKeyPressed(e->KeyCode, true);
  588. }
  589.  
  590. void CMainForm::pic3D_KeyUp(::Object *sender, ::KeyEventArgs *e)
  591. {
  592.     Engine->SetKeyPressed(e->KeyCode, false);
  593. }
  594.  
  595. void CMainForm::treWorld_AfterSelect(::Object *sender, ::TreeViewEventArgs *e)
  596. {
  597.     this->lstProperties->BeginUpdate();
  598.     this->lstProperties->Items->Clear();
  599.  
  600.     if(this->treWorld->SelectedNode == NULL)
  601.     {
  602.         Engine->SetHighlightObject(NULL);
  603.     }
  604.     else
  605.     {
  606.         CWorldObjectTreeNode *WorldObjectTreeNode = static_cast<CWorldObjectTreeNode*>(this->treWorld->SelectedNode);
  607.         CWorldObject *WorldObject = WorldObjectTreeNode->Selected();
  608.         Engine->SetHighlightObject(WorldObject);
  609.  
  610.         if(WorldObjectTreeNode->GetType() == WorldObjectType::Entity)
  611.         {
  612.             CEntity *Entity = static_cast<CEntity*>(WorldObject);
  613.             ArrayList *ArgVals;
  614.             CArgVal *ArgVal;
  615.             ListViewItem *Row;
  616.  
  617.             ArgVals = Entity->GetArgVals();
  618.  
  619.             for(int i = 0; i < ArgVals->Count; i++)
  620.             {
  621.                 ArgVal = static_cast<CArgVal*>(ArgVals->get_Item(i));
  622.  
  623.                 Row = new ListViewItem();
  624.                 Row->Text = ArgVal->GetArg();
  625.                 Row->SubItems->Add(ArgVal->GetVal());
  626.  
  627.                 this->lstProperties->Items->Add(Row);
  628.             }
  629.  
  630.             /*Row = new ListViewItem();
  631.             Row->Text = "brushes";
  632.             Row->SubItems->Add(Entity->GetBrushes()->Count.ToString());
  633.  
  634.             this->lstProperties->Items->Add(Row);*/
  635.         }
  636.         /*else if(WorldObjectTreeNode->GetType() == WorldObjectType::Brush)
  637.         {
  638.             ListViewItem *Row;
  639.             CBrush *Brush = static_cast<CBrush*>(WorldObject);
  640.  
  641.             Row = new ListViewItem();
  642.             Row->Text = "faces";
  643.             Row->SubItems->Add(Brush->GetFaces()->Count.ToString());
  644.  
  645.             this->lstProperties->Items->Add(Row);
  646.         }*/
  647.         else if(WorldObjectTreeNode->GetType() == WorldObjectType::Face)
  648.         {
  649.             ListViewItem *Row;
  650.             CFace *Face = static_cast<CFace*>(WorldObject);
  651.             
  652.             Row = new ListViewItem();
  653.             Row->Text = "texture";
  654.             Row->SubItems->Add(Face->GetTexture(Engine->GetTextureManager()));
  655.  
  656.             this->lstProperties->Items->Add(Row);
  657.  
  658.             Row = new ListViewItem();
  659.             Row->Text = "shift";
  660.             Row->SubItems->Add(String::Concat(Face->GetUShift().ToString("0.00"), ", ", Face->GetVShift().ToString("0.00")));
  661.  
  662.             this->lstProperties->Items->Add(Row);
  663.  
  664.             Row = new ListViewItem();
  665.             Row->Text = "scale";
  666.             Row->SubItems->Add(String::Concat(Face->GetUScale().ToString("0.00"), ", ", Face->GetVScale().ToString("0.00")));
  667.  
  668.             this->lstProperties->Items->Add(Row);
  669.  
  670.             Row = new ListViewItem();
  671.             Row->Text = "rotation";
  672.             Row->SubItems->Add(Face->GetRotation().ToString("0.00"));
  673.  
  674.             this->lstProperties->Items->Add(Row);
  675.  
  676.             /*Row = new ListViewItem();
  677.             Row->Text = "vertices";
  678.             Row->SubItems->Add(Face->GetVertexCount().ToString());
  679.  
  680.             this->lstProperties->Items->Add(Row);*/
  681.         }
  682.     }
  683.  
  684.     this->lstProperties->EndUpdate();
  685. }
  686.  
  687. void CMainForm::lstProperties_Resize(::Object *sender, ::EventArgs *e)
  688. {
  689.     this->lstProperties->Columns->get_Item(0)->Width = this->lstProperties->ClientSize.Width / 2;
  690.     this->lstProperties->Columns->get_Item(1)->Width = this->lstProperties->ClientSize.Width / 2;
  691. }
  692.  
  693. void CMainForm::cmdOpen_Click(::Object *sender, ::EventArgs *e)
  694. {
  695.     if(dlgOpenMAPFile->ShowDialog() == DialogResult::OK)
  696.     {
  697.         LoadWorld(dlgOpenMAPFile->FileName);
  698.     }
  699. }
  700.  
  701. void CMainForm::cmdRecentFile_Click(::Object *sender, ::EventArgs *e)
  702. {
  703.     LoadWorld(static_cast<MenuItem*>(sender)->Text);
  704. }
  705.  
  706. void CMainForm::cmdExit_Click(::Object *sender, ::EventArgs *e)
  707. {
  708.     this->Exit();
  709. }
  710.  
  711. void CMainForm::cmdTextured_Click(::Object *sender, ::EventArgs *e)
  712. {
  713.     Config->eRenderMode = RenderMode::Textured;
  714.  
  715.     cmdTextured->Checked = true;
  716.     cmdSolid->Checked = false;
  717.     cmdWireFrame->Checked = false;
  718.     cmdPoints->Checked = false;
  719. }
  720.  
  721. void CMainForm::cmdSolid_Click(::Object *sender, ::EventArgs *e)
  722. {
  723.     Config->eRenderMode = RenderMode::Solid;
  724.  
  725.     cmdTextured->Checked = false;
  726.     cmdSolid->Checked = true;
  727.     cmdWireFrame->Checked = false;
  728.     cmdPoints->Checked = false;
  729. }
  730.  
  731. void CMainForm::cmdWireFrame_Click(::Object *sender, ::EventArgs *e)
  732. {
  733.     Config->eRenderMode = RenderMode::WireFrame;
  734.  
  735.     cmdTextured->Checked = false;
  736.     cmdSolid->Checked = false;
  737.     cmdWireFrame->Checked = true;
  738.     cmdPoints->Checked = false;
  739. }
  740.  
  741. void CMainForm::cmdPoints_Click(::Object *sender, ::EventArgs *e)
  742. {
  743.     Config->eRenderMode = RenderMode::Points;
  744.  
  745.     cmdTextured->Checked = false;
  746.     cmdSolid->Checked = false;
  747.     cmdWireFrame->Checked = false;
  748.     cmdPoints->Checked = true;
  749. }
  750.  
  751. void CMainForm::cmdDrawSpecialTextures_Click(::Object *sender, ::EventArgs *e)
  752. {
  753.     Config->bDrawSpecialTextures = ! Config->bDrawSpecialTextures;
  754.  
  755.     cmdDrawSpecialTextures->Checked = Config->bDrawSpecialTextures;
  756. }
  757.  
  758. void CMainForm::cmdDrawSelection_Click(::Object *sender, ::EventArgs *e)
  759. {
  760.     Config->bDrawSelection = ! Config->bDrawSelection;
  761.  
  762.     cmdDrawSelection->Checked = Config->bDrawSelection;
  763. }
  764.  
  765. void CMainForm::cmdDrawPointFile_Click(::Object *sender, ::EventArgs *e)
  766. {
  767.     Config->bDrawPointFile = ! Config->bDrawPointFile;
  768.  
  769.     cmdDrawPointFile->Checked = Config->bDrawPointFile;
  770. }
  771.  
  772. void CMainForm::cmdOutlineScene_Click(::Object *sender, ::EventArgs *e)
  773. {
  774.     Config->bOutlineScene = ! Config->bOutlineScene;
  775.  
  776.     cmdOutlineScene->Checked = Config->bOutlineScene;
  777. }
  778.  
  779. void CMainForm::cmdLightScene_Click(::Object *sender, ::EventArgs *e)
  780. {
  781.     Config->bLightScene = ! Config->bLightScene;
  782.  
  783.     cmdLightScene->Checked = Config->bLightScene;
  784. }
  785.  
  786. void CMainForm::cmdFog_Click(::Object *sender, ::EventArgs *e)
  787. {
  788.     Config->bFog = ! Config->bFog;
  789.  
  790.     cmdFog->Checked = Config->bFog;
  791. }
  792.  
  793. void CMainForm::cmdNearest_Click(::Object *sender, ::EventArgs *e)
  794. {
  795.     Config->eTextureFilter = TextureFilter::Nearest;
  796.  
  797.     this->cmdNearest->Checked = true;
  798.     this->cmdLinear->Checked = false;
  799.     this->cmdMipNearest->Checked = false;
  800.     this->cmdMipLinear->Checked = false;
  801.     this->cmdMipBilinear->Checked = false;
  802.     this->cmdMipTrilinear->Checked = false;
  803.     this->cmdMipIsotropic->Checked = false;
  804.     this->cmdMipAnisotropic->Checked = false;
  805.  
  806.     this->Engine->UpdateTextureFilter();
  807. }
  808.  
  809. void CMainForm::cmdLinear_Click(::Object *sender, ::EventArgs *e)
  810. {
  811.     Config->eTextureFilter = TextureFilter::Linear;
  812.  
  813.     this->cmdNearest->Checked = false;
  814.     this->cmdLinear->Checked = true;
  815.     this->cmdMipNearest->Checked = false;
  816.     this->cmdMipLinear->Checked = false;
  817.     this->cmdMipBilinear->Checked = false;
  818.     this->cmdMipTrilinear->Checked = false;
  819.     this->cmdMipIsotropic->Checked = false;
  820.     this->cmdMipAnisotropic->Checked = false;
  821.  
  822.     this->Engine->UpdateTextureFilter();
  823. }
  824.  
  825. void CMainForm::cmdMipNearest_Click(::Object *sender, ::EventArgs *e)
  826. {
  827.     Config->eTextureFilter = TextureFilter::MipNearest;
  828.  
  829.     this->cmdNearest->Checked = false;
  830.     this->cmdLinear->Checked = false;
  831.     this->cmdMipNearest->Checked = true;
  832.     this->cmdMipLinear->Checked = false;
  833.     this->cmdMipBilinear->Checked = false;
  834.     this->cmdMipTrilinear->Checked = false;
  835.     this->cmdMipIsotropic->Checked = false;
  836.     this->cmdMipAnisotropic->Checked = false;
  837.  
  838.     this->Engine->UpdateTextureFilter();
  839. }
  840.  
  841. void CMainForm::cmdMipLinear_Click(::Object *sender, ::EventArgs *e)
  842. {
  843.     Config->eTextureFilter = TextureFilter::MipLinear;
  844.  
  845.     this->cmdNearest->Checked = false;
  846.     this->cmdLinear->Checked = false;
  847.     this->cmdMipNearest->Checked = false;
  848.     this->cmdMipLinear->Checked = true;
  849.     this->cmdMipBilinear->Checked = false;
  850.     this->cmdMipTrilinear->Checked = false;
  851.     this->cmdMipIsotropic->Checked = false;
  852.     this->cmdMipAnisotropic->Checked = false;
  853.  
  854.     this->Engine->UpdateTextureFilter();
  855. }
  856.  
  857. void CMainForm::cmdMipBilinear_Click(::Object *sender, ::EventArgs *e)
  858. {
  859.     Config->eTextureFilter = TextureFilter::MipBilinear;
  860.  
  861.     this->cmdNearest->Checked = false;
  862.     this->cmdLinear->Checked = false;
  863.     this->cmdMipNearest->Checked = false;
  864.     this->cmdMipLinear->Checked = false;
  865.     this->cmdMipBilinear->Checked = true;
  866.     this->cmdMipTrilinear->Checked = false;
  867.     this->cmdMipIsotropic->Checked = false;
  868.     this->cmdMipAnisotropic->Checked = false;
  869.  
  870.     this->Engine->UpdateTextureFilter();
  871. }
  872.  
  873. void CMainForm::cmdMipTrilinear_Click(::Object *sender, ::EventArgs *e)
  874. {
  875.     Config->eTextureFilter = TextureFilter::MipTrilinear;
  876.  
  877.     this->cmdNearest->Checked = false;
  878.     this->cmdLinear->Checked = false;
  879.     this->cmdMipNearest->Checked = false;
  880.     this->cmdMipLinear->Checked = false;
  881.     this->cmdMipBilinear->Checked = false;
  882.     this->cmdMipTrilinear->Checked = true;
  883.     this->cmdMipIsotropic->Checked = false;
  884.     this->cmdMipAnisotropic->Checked = false;
  885.  
  886.     this->Engine->UpdateTextureFilter();
  887. }
  888.  
  889. void CMainForm::cmdMipIsotropic_Click(::Object *sender, ::EventArgs *e)
  890. {
  891.     if(!Engine->TestExtension("GL_EXT_texture_filter_anisotropic"))
  892.     {
  893.         return;
  894.     }
  895.  
  896.     Config->eTextureFilter = TextureFilter::MipIsotropic;
  897.  
  898.     this->cmdNearest->Checked = false;
  899.     this->cmdLinear->Checked = false;
  900.     this->cmdMipNearest->Checked = false;
  901.     this->cmdMipLinear->Checked = false;
  902.     this->cmdMipBilinear->Checked = false;
  903.     this->cmdMipTrilinear->Checked = false;
  904.     this->cmdMipIsotropic->Checked = true;
  905.     this->cmdMipAnisotropic->Checked = false;
  906.  
  907.     this->Engine->UpdateTextureFilter();
  908. }
  909.  
  910. void CMainForm::cmdMipAnisotropic_Click(::Object *sender, ::EventArgs *e)
  911. {
  912.     if(!Engine->TestExtension("GL_EXT_texture_filter_anisotropic"))
  913.     {
  914.         return;
  915.     }
  916.  
  917.     Config->eTextureFilter = TextureFilter::MipAnisotropic;
  918.  
  919.     this->cmdNearest->Checked = false;
  920.     this->cmdLinear->Checked = false;
  921.     this->cmdMipNearest->Checked = false;
  922.     this->cmdMipLinear->Checked = false;
  923.     this->cmdMipBilinear->Checked = false;
  924.     this->cmdMipTrilinear->Checked = false;
  925.     this->cmdMipIsotropic->Checked = false;
  926.     this->cmdMipAnisotropic->Checked = true;
  927.  
  928.     this->Engine->UpdateTextureFilter();
  929. }
  930.  
  931. void CMainForm::cmdLoadPointFile_Click(::Object *sender, ::EventArgs *e)
  932. {
  933.     if(dlgOpenPTSFile->ShowDialog() == DialogResult::OK)
  934.     {
  935.         LoadPointFile(dlgOpenPTSFile->FileName);
  936.     }
  937. }
  938.  
  939. void CMainForm::cmdUnloadPointFile_Click(::Object *sender, ::EventArgs *e)
  940. {
  941.     UnloadPointFile();
  942. }
  943.  
  944. void CMainForm::cmdAbout_Click(::Object *sender, ::EventArgs *e)
  945. {
  946.     AboutForm->ShowDialog();
  947. }
  948.  
  949. void CMainForm::GetHalfLifePath()
  950. {
  951.     Object *HLPath = Config->ReadKey(Microsoft::Win32::Registry::LocalMachine, "SOFTWARE\\Valve\\Half-Life", "InstallPath");
  952.  
  953.     if(HLPath != NULL)
  954.     {
  955.         Config->sHalfLifePath = static_cast<String*>(HLPath);
  956.  
  957.         if(Config->sHalfLifePath->Length != 0 && !Config->sHalfLifePath->EndsWith("\\"))
  958.         {
  959.             Config->sHalfLifePath = String::Concat(Config->sHalfLifePath, "\\");
  960.         }
  961.     }
  962. }
  963.  
  964. bool CMainForm::WriteConfigFile(String *sFile)
  965. {
  966.     txtConsole->Print(String::Concat(S"Writing ", sFile, S"..."), Color::Green);
  967.  
  968.     StreamWriter *ConfigFile;
  969.  
  970.     try
  971.     {
  972.         ConfigFile = new StreamWriter(sFile, false, System::Text::Encoding::ASCII);
  973.     }
  974.     catch(Exception *e)
  975.     {
  976.         txtConsole->Print(String::Concat(S"Error writing ", sFile, S": ", e->Message, S"\n"), Color::Red);
  977.         return false;
  978.     }
  979.  
  980.     try
  981.     {
  982.         ConfigFile->WriteLine("[General]");
  983.         ConfigFile->WriteLine("");
  984.  
  985.         ConfigFile->WriteLine(String::Concat("General.RecentMAPCount = ", Config->iRecentMAPCount.ToString()));
  986.  
  987.         ConfigFile->WriteLine("");
  988.         ConfigFile->WriteLine("[Engine]");
  989.         ConfigFile->WriteLine("");
  990.  
  991.         ConfigFile->WriteLine(String::Concat("Engine.ColorBits = ", Config->bColorBits.ToString()));
  992.         ConfigFile->WriteLine(String::Concat("Engine.DepthBits = ", Config->bDepthBits.ToString()));
  993.  
  994.         ConfigFile->WriteLine(String::Concat("Engine.BackColor.R = ", Config->cBackColor.R.ToString("0.000")));
  995.         ConfigFile->WriteLine(String::Concat("Engine.BackColor.G = ", Config->cBackColor.G.ToString("0.000")));
  996.         ConfigFile->WriteLine(String::Concat("Engine.BackColor.B = ", Config->cBackColor.B.ToString("0.000")));
  997.         ConfigFile->WriteLine(String::Concat("Engine.BackColor.A = ", Config->cBackColor.A.ToString("0.000")));
  998.  
  999.         ConfigFile->WriteLine(String::Concat("Engine.ForeColor.R = ", Config->cForeColor.R.ToString("0.000")));
  1000.         ConfigFile->WriteLine(String::Concat("Engine.ForeColor.G = ", Config->cForeColor.G.ToString("0.000")));
  1001.         ConfigFile->WriteLine(String::Concat("Engine.ForeColor.B = ", Config->cForeColor.B.ToString("0.000")));
  1002.         ConfigFile->WriteLine(String::Concat("Engine.ForeColor.A = ", Config->cForeColor.A.ToString("0.000")));
  1003.  
  1004.         ConfigFile->WriteLine(String::Concat("Engine.HighlightColor.R = ", Config->cHighlightColor.R.ToString("0.000")));
  1005.         ConfigFile->WriteLine(String::Concat("Engine.HighlightColor.G = ", Config->cHighlightColor.G.ToString("0.000")));
  1006.         ConfigFile->WriteLine(String::Concat("Engine.HighlightColor.B = ", Config->cHighlightColor.B.ToString("0.000")));
  1007.         ConfigFile->WriteLine(String::Concat("Engine.HighlightColor.A = ", Config->cHighlightColor.A.ToString("0.000")));
  1008.  
  1009.         ConfigFile->WriteLine(String::Concat("Engine.OutlineColor.R = ", Config->cOutlineColor.R.ToString("0.000")));
  1010.         ConfigFile->WriteLine(String::Concat("Engine.OutlineColor.G = ", Config->cOutlineColor.G.ToString("0.000")));
  1011.         ConfigFile->WriteLine(String::Concat("Engine.OutlineColor.B = ", Config->cOutlineColor.B.ToString("0.000")));
  1012.         ConfigFile->WriteLine(String::Concat("Engine.OutlineColor.A = ", Config->cOutlineColor.A.ToString("0.000")));
  1013.  
  1014.         ConfigFile->WriteLine("");
  1015.         ConfigFile->WriteLine("[Frustum]");
  1016.         ConfigFile->WriteLine("");
  1017.  
  1018.         ConfigFile->WriteLine(String::Concat("Frustum.FieldOfView = ", Config->fFrustumFieldOfView.ToString("0.000")));
  1019.         ConfigFile->WriteLine(String::Concat("Frustum.ZNear = ", Config->fFrustumZNear.ToString("0.000")));
  1020.         ConfigFile->WriteLine(String::Concat("Frustum.ZFar = ", Config->fFrustumZFar.ToString("0.000")));
  1021.  
  1022.         ConfigFile->WriteLine("");
  1023.         ConfigFile->WriteLine("[Fog]");
  1024.         ConfigFile->WriteLine("");
  1025.  
  1026.         ConfigFile->WriteLine(String::Concat("Fog.Enabled = ", Config->bFog.ToString()));
  1027.         ConfigFile->WriteLine(String::Concat("Fog.Mode = ", __box(Config->eFogMode)->ToString()));
  1028.         ConfigFile->WriteLine(String::Concat("Fog.Density = ", Config->fFogDensity.ToString("0.000")));
  1029.         ConfigFile->WriteLine(String::Concat("Fog.Start = ", Config->fFogStart.ToString("0.000")));
  1030.         ConfigFile->WriteLine(String::Concat("Fog.End = ", Config->fFogEnd.ToString("0.000")));
  1031.         ConfigFile->WriteLine(String::Concat("Fog.Color.R = ", Config->cFogColor.R.ToString("0.000")));
  1032.         ConfigFile->WriteLine(String::Concat("Fog.Color.G = ", Config->cFogColor.G.ToString("0.000")));
  1033.         ConfigFile->WriteLine(String::Concat("Fog.Color.B = ", Config->cFogColor.B.ToString("0.000")));
  1034.         ConfigFile->WriteLine(String::Concat("Fog.Color.A = ", Config->cFogColor.A.ToString("0.000")));
  1035.  
  1036.         ConfigFile->WriteLine("");
  1037.         ConfigFile->WriteLine("[Camera]");
  1038.         ConfigFile->WriteLine("");
  1039.  
  1040.         ConfigFile->WriteLine(String::Concat("Camera.Invert = ", Config->bInvertCamera.ToString()));
  1041.         ConfigFile->WriteLine(String::Concat("Camera.Speed = ", Config->fCameraSpeed.ToString("0.000")));
  1042.         ConfigFile->WriteLine(String::Concat("Camera.Boost = ", Config->fCameraBoost.ToString("0.000")));
  1043.  
  1044.         ConfigFile->WriteLine("");
  1045.         ConfigFile->WriteLine("[Renderer]");
  1046.         ConfigFile->WriteLine("");
  1047.  
  1048.         ConfigFile->WriteLine(String::Concat("Renderer.DrawSpecialTextures = ", Config->bDrawSpecialTextures.ToString()));
  1049.         ConfigFile->WriteLine(String::Concat("Renderer.DrawSelection = ", Config->bDrawSelection.ToString()));
  1050.         ConfigFile->WriteLine(String::Concat("Renderer.DrawPointFile = ", Config->bDrawPointFile.ToString()));
  1051.         ConfigFile->WriteLine(String::Concat("Renderer.LightScene = ", Config->bLightScene.ToString()));
  1052.         ConfigFile->WriteLine(String::Concat("Renderer.OutlineScene = ", Config->bOutlineScene.ToString()));
  1053.  
  1054.         ConfigFile->WriteLine(String::Concat("Renderer.RenderMode = ", __box(Config->eRenderMode)->ToString()));
  1055.         ConfigFile->WriteLine(String::Concat("Renderer.TextureFilter = ", __box(Config->eTextureFilter)->ToString()));
  1056.  
  1057.         ConfigFile->WriteLine("");
  1058.         ConfigFile->WriteLine("[Textures]");
  1059.         ConfigFile->WriteLine("");
  1060.  
  1061.         ConfigFile->WriteLine(String::Concat("Textures.HalfLifePath = ", Config->sHalfLifePath));
  1062.  
  1063.         ConfigFile->WriteLine("");
  1064.         ConfigFile->WriteLine("[Recent Files]");
  1065.         ConfigFile->WriteLine("");
  1066.  
  1067.         for(int i = RecentFiles->Count - 1; i >= 0; i--)
  1068.         {
  1069.             ConfigFile->WriteLine(String::Concat("RecentFiles.RecentFile = ", static_cast<String*>(RecentFiles->get_Item(i))));
  1070.         }
  1071.     }
  1072.     catch(Exception *e)
  1073.     {
  1074.         txtConsole->Print(String::Concat(S"Error writing ", sFile, S": ", e->Message, S"\n"), Color::Red);
  1075.         ConfigFile->Close();
  1076.         return false;
  1077.     }
  1078.  
  1079.     ConfigFile->Close();
  1080.  
  1081.     txtConsole->Print("done.\n", Color::Green);
  1082.  
  1083.     return true;
  1084. }
  1085.  
  1086. bool CMainForm::LoadConfigFile(String *sFile)
  1087. {
  1088.     if(!File::Exists(sFile))
  1089.         return false;
  1090.  
  1091.     txtConsole->Print(String::Concat(S"Loading ", sFile, S"..."), Color::Green);
  1092.  
  1093.     StreamReader *ConfigFile;
  1094.  
  1095.     try
  1096.     {
  1097.         ConfigFile = new StreamReader(sFile, System::Text::Encoding::ASCII);
  1098.     }
  1099.     catch(Exception *e)
  1100.     {
  1101.         txtConsole->Print(String::Concat(S"Error loading ", sFile, S": ", e->Message, S"\n"), Color::Red);
  1102.         return false;
  1103.     }
  1104.  
  1105.     try
  1106.     {
  1107.         String *sLine, *sArg, *sVal;
  1108.  
  1109.         while((sLine = ConfigFile->ReadLine()) != NULL)
  1110.         {
  1111.             if(!ProcessLine(sLine, &sArg, &sVal))
  1112.                 continue;
  1113.  
  1114.             try
  1115.             {
  1116.                 // General
  1117.                 if(sArg->Equals("general.recentmapcount"))
  1118.                 {
  1119.                     Config->iRecentMAPCount = Convert::ToInt32(sVal);
  1120.                 }
  1121.  
  1122.                 // Engine
  1123.                 else if(sArg->Equals("engine.colorbits"))
  1124.                 {
  1125.                     Config->bColorBits = Convert::ToByte(sVal);
  1126.                 }
  1127.                 else if(sArg->Equals("engine.depthbits"))
  1128.                 {
  1129.                     Config->bDepthBits = Convert::ToByte(sVal);
  1130.                 }
  1131.                 else if(sArg->Equals("engine.backcolor.r"))
  1132.                 {
  1133.                     Config->cBackColor.R = Convert::ToSingle(sVal);
  1134.                 }
  1135.                 else if(sArg->Equals("engine.backcolor.g"))
  1136.                 {
  1137.                     Config->cBackColor.G = Convert::ToSingle(sVal);
  1138.                 }
  1139.                 else if(sArg->Equals("engine.backcolor.b"))
  1140.                 {
  1141.                     Config->cBackColor.B = Convert::ToSingle(sVal);
  1142.                 }
  1143.                 else if(sArg->Equals("engine.backcolor.a"))
  1144.                 {
  1145.                     Config->cBackColor.A = Convert::ToSingle(sVal);
  1146.                 }
  1147.                 else if(sArg->Equals("engine.forecolor.r"))
  1148.                 {
  1149.                     Config->cForeColor.R = Convert::ToSingle(sVal);
  1150.                 }
  1151.                 else if(sArg->Equals("engine.forecolor.g"))
  1152.                 {
  1153.                     Config->cForeColor.G = Convert::ToSingle(sVal);
  1154.                 }
  1155.                 else if(sArg->Equals("engine.forecolor.b"))
  1156.                 {
  1157.                     Config->cForeColor.B = Convert::ToSingle(sVal);
  1158.                 }
  1159.                 else if(sArg->Equals("engine.forecolor.a"))
  1160.                 {
  1161.                     Config->cForeColor.A = Convert::ToSingle(sVal);
  1162.                 }
  1163.                 else if(sArg->Equals("engine.highlightcolor.r"))
  1164.                 {
  1165.                     Config->cHighlightColor.R = Convert::ToSingle(sVal);
  1166.                 }
  1167.                 else if(sArg->Equals("engine.highlightcolor.g"))
  1168.                 {
  1169.                     Config->cHighlightColor.G = Convert::ToSingle(sVal);
  1170.                 }
  1171.                 else if(sArg->Equals("engine.highlightcolor.b"))
  1172.                 {
  1173.                     Config->cHighlightColor.B = Convert::ToSingle(sVal);
  1174.                 }
  1175.                 else if(sArg->Equals("engine.highlightcolor.a"))
  1176.                 {
  1177.                     Config->cHighlightColor.A = Convert::ToSingle(sVal);
  1178.                 }
  1179.                 else if(sArg->Equals("engine.outlinecolor.r"))
  1180.                 {
  1181.                     Config->cOutlineColor.R = Convert::ToSingle(sVal);
  1182.                 }
  1183.                 else if(sArg->Equals("engine.outlinecolor.g"))
  1184.                 {
  1185.                     Config->cOutlineColor.G = Convert::ToSingle(sVal);
  1186.                 }
  1187.                 else if(sArg->Equals("engine.outlinecolor.b"))
  1188.                 {
  1189.                     Config->cOutlineColor.B = Convert::ToSingle(sVal);
  1190.                 }
  1191.                 else if(sArg->Equals("engine.outlinecolor.a"))
  1192.                 {
  1193.                     Config->cOutlineColor.A = Convert::ToSingle(sVal);
  1194.                 }
  1195.  
  1196.                 // Frustum
  1197.                 else if(sArg->Equals("frustum.fieldofview"))
  1198.                 {
  1199.                     Config->fFrustumFieldOfView = Convert::ToBoolean(sVal);
  1200.                 }
  1201.                 else if(sArg->Equals("frustum.znear"))
  1202.                 {
  1203.                     Config->fFrustumZNear = Convert::ToBoolean(sVal);
  1204.                 }
  1205.                 else if(sArg->Equals("frustum.zfar"))
  1206.                 {
  1207.                     Config->fFrustumZFar = Convert::ToBoolean(sVal);
  1208.                 }
  1209.  
  1210.                 // Fog
  1211.                 else if(sArg->Equals("fog.enabled"))
  1212.                 {
  1213.                     Config->bFog = Convert::ToBoolean(sVal);
  1214.                 }
  1215.                 else if(sArg->Equals("fog.density"))
  1216.                 {
  1217.                     Config->fFogDensity = Convert::ToSingle(sVal);
  1218.                 }
  1219.                 else if(sArg->Equals("fog.start"))
  1220.                 {
  1221.                     Config->fFogStart = Convert::ToSingle(sVal);
  1222.                 }
  1223.                 else if(sArg->Equals("fog.end"))
  1224.                 {
  1225.                     Config->fFogEnd = Convert::ToSingle(sVal);
  1226.                 }
  1227.                 else if(sArg->Equals("fog.color.r"))
  1228.                 {
  1229.                     Config->cFogColor.R = Convert::ToSingle(sVal);
  1230.                 }
  1231.                 else if(sArg->Equals("fog.color.g"))
  1232.                 {
  1233.                     Config->cFogColor.G = Convert::ToSingle(sVal);
  1234.                 }
  1235.                 else if(sArg->Equals("fog.color.b"))
  1236.                 {
  1237.                     Config->cFogColor.B = Convert::ToSingle(sVal);
  1238.                 }
  1239.                 else if(sArg->Equals("fog.color.a"))
  1240.                 {
  1241.                     Config->cFogColor.A = Convert::ToSingle(sVal);
  1242.                 }
  1243.                 else if(sArg->Equals("fog.mode"))
  1244.                 {
  1245.                     Config->eFogMode = *static_cast<__box FogMode::FogMode*>(Enum::Parse(__typeof(FogMode::FogMode), sVal, false));
  1246.                 }
  1247.  
  1248.                 // Camera
  1249.                 else if(sArg->Equals("camera.invert"))
  1250.                 {
  1251.                     Config->bInvertCamera = Convert::ToBoolean(sVal);
  1252.                 }
  1253.                 else if(sArg->Equals("camera.speed"))
  1254.                 {
  1255.                     Config->fCameraSpeed = Convert::ToSingle(sVal);
  1256.                 }
  1257.                 else if(sArg->Equals("camera.boost"))
  1258.                 {
  1259.                     Config->fCameraBoost = Convert::ToSingle(sVal);
  1260.                 }
  1261.  
  1262.                 // Renderer
  1263.                 else if(sArg->Equals("renderer.drawspecialtextures"))
  1264.                 {
  1265.                     Config->bDrawSpecialTextures = Convert::ToBoolean(sVal);
  1266.                 }
  1267.                 else if(sArg->Equals("renderer.drawselection"))
  1268.                 {
  1269.                     Config->bDrawSelection = Convert::ToBoolean(sVal);
  1270.                 }
  1271.                 else if(sArg->Equals("renderer.drawpointfile"))
  1272.                 {
  1273.                     Config->bDrawPointFile = Convert::ToBoolean(sVal);
  1274.                 }
  1275.                 else if(sArg->Equals("renderer.lightscene"))
  1276.                 {
  1277.                     Config->bLightScene = Convert::ToBoolean(sVal);
  1278.                 }
  1279.                 else if(sArg->Equals("renderer.outlinescene"))
  1280.                 {
  1281.                     Config->bOutlineScene = Convert::ToBoolean(sVal);
  1282.                 }
  1283.                 else if(sArg->Equals("renderer.rendermode"))
  1284.                 {
  1285.                     Config->eRenderMode = *static_cast<__box RenderMode::RenderMode*>(Enum::Parse(__typeof(RenderMode::RenderMode), sVal, false));
  1286.                 }
  1287.                 else if(sArg->Equals("renderer.texturefilter"))
  1288.                 {
  1289.                     Config->eTextureFilter = *static_cast<__box TextureFilter::TextureFilter*>(Enum::Parse(__typeof(TextureFilter::TextureFilter), sVal, false));
  1290.                 }
  1291.  
  1292.                 //Textures
  1293.                 else if(sArg->Equals("textures.halflifepath"))
  1294.                 {
  1295.                     if(sVal->Length != 0 && !sVal->EndsWith("\\"))
  1296.                     {
  1297.                         sVal = String::Concat(sVal, "\\");
  1298.                     }
  1299.  
  1300.                     Config->sHalfLifePath = sVal;
  1301.                 }
  1302.  
  1303.                 // Recent Files
  1304.                 else if(sArg->Equals("recentfiles.recentfile"))
  1305.                 {
  1306.                     AddRecentFile(sVal);
  1307.                 }
  1308.             }
  1309.             catch(Exception *e)
  1310.             {
  1311.                 continue;
  1312.             }
  1313.         }
  1314.     }
  1315.     catch(Exception *e)
  1316.     {
  1317.         txtConsole->Print(String::Concat(S"Error loading ", sFile, S": ", e->Message, S"\n"), Color::Red);
  1318.         ConfigFile->Close();
  1319.         return false;
  1320.     }
  1321.  
  1322.     ConfigFile->Close();
  1323.  
  1324.     UpdateRecentFiles();
  1325.  
  1326.     txtConsole->Print("done.\n", Color::Green);
  1327.  
  1328.     return true;
  1329. }
  1330.  
  1331. bool CMainForm::ProcessLine(String *sLine, String **sArg, String **sVal)
  1332. {
  1333.     *sArg = NULL;
  1334.     *sVal = NULL;
  1335.  
  1336.     sLine = sLine->Trim();
  1337.  
  1338.     if(sLine->IndexOf("//") != -1)
  1339.     {
  1340.         sLine = sLine->Remove(sLine->IndexOf("//"), sLine->Length)->Trim();
  1341.  
  1342.         if(sLine->Length == 0)
  1343.             return false;
  1344.     }
  1345.  
  1346.     if(sLine->IndexOf("=") == -1)
  1347.         return false;
  1348.  
  1349.     *sArg = sLine->Substring(0, sLine->IndexOf("="))->Trim()->ToLower();
  1350.     *sVal = sLine->Substring(sLine->IndexOf("=") + 1)->Trim();
  1351.  
  1352.     return true;
  1353. }